package top.mccat.web.controller.system;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import top.mccat.common.core.domain.AjaxResult;
import top.mccat.common.utils.StringUtils;
import top.mccat.system.domain.EmployeeExcellent;
import top.mccat.system.domain.EmployeePunch;
import top.mccat.system.domain.EmployeeVacation;
import top.mccat.system.domain.SysNotice;
import top.mccat.system.service.*;
import top.mccat.web.controller.tool.DateUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author Raven
 */
@RestController
@RequestMapping("/system/main")
public class MainPageController {
    @Resource
    private IEmployeePunchService punchService;
    @Resource
    private ISysNoticeService noticeService;
    @Resource
    private IEmployeeVacationService vacationService;
    @Resource
    private IEmployeeExcellentService employeeExcellentService;
    @Resource
    private ISysUserService sysUserService;
    @Value("${date.start}")
    private String arriveLateTime;
    @Value("${date.end}")
    private String leaveEarlyTime;

    /**
     * 获取基础信息
     * @param userName 用户名数据
     * @return json数据
     */
    @GetMapping("/essentials/{userName}")
    public AjaxResult getEmployeeExtra(@PathVariable String userName){
        if(StringUtils.isBlank(userName)){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"userName不能为空！");
        }
        //执行参数init
        Long userId = sysUserService.selectUserByUserName(userName).getUserId();
        EmployeePunch employeePunch = punchService.selectOneEmployeePunchToday(userId);
        Integer punchTime = punchService.selectEmployeePunchTimeMonth(userId);
        Integer workDays = DateUtils.getDaysWithoutWeekend();
        SysNotice sysNotice = noticeService.selectNewNotice();
        String content = sysNotice.getNoticeContent();
        sysNotice.setNoticeContent(sysNotice.getNoticeContent().substring(3,content.length()-4));
        EmployeeVacation vacation = vacationService.selectDisplayVacation();
        EmployeeExcellent excellent = employeeExcellentService.selectEmployeeNowMonth(userId);
        //执行报文包装
        AjaxResult ajaxResult = AjaxResult.success();
        ajaxResult.put("userId",userId);
        ajaxResult.put("todayPunch",employeePunch);
        ajaxResult.put("punchTime",punchTime);
        ajaxResult.put("sysNotice",sysNotice.getNoticeContent());
        ajaxResult.put("workDays",workDays);
        ajaxResult.put("vacation",vacation);
        //如果为空直接显示前端消息即可
        ajaxResult.put("excellent",excellent!=null);
        return ajaxResult;
    }

    /**
     * 设置打卡时间，默认配置检查时间为早上9点后算迟到，晚上18:00算早退
     * @param userId 用户 id
     * @return ajax
     */
    @PostMapping("/workPunch/{userId}")
    public AjaxResult workPunch(@PathVariable Long userId){
        if(userId==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"userId不能为空！");
        }
        AjaxResult ajaxResult = AjaxResult.success();
        EmployeePunch employeePunch = punchService.selectOneEmployeePunchToday(userId);
        Date now = new Date();
        if(employeePunch==null){
            //如果为空则绑定用户id
            employeePunch = new EmployeePunch();
            employeePunch.setUserId(userId);
        }else {
            //如果已打卡禁止打卡
            if(employeePunch.getStartTime()!=null){
                return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"您已进行过上班打卡，请勿重复打卡！");
            }
        }
        //如果超过则算迟到，反之算早退，如果下班正常打卡则取消早退状态
        employeePunch.setStartTime(now);
        if(DateUtils.workPunchCheck(now,arriveLateTime)){
            employeePunch.setPunchStatus(EmployeePunch.PunchStatus.ArriveLate.getStatus());
        }else{
            employeePunch.setPunchStatus(EmployeePunch.PunchStatus.EarlyLeave.getStatus());
        }
        punchService.insertEmployeePunch(employeePunch);
        ajaxResult.put("punchTime",DateUtils.formatTime(now));
        return ajaxResult;
    }

    /**
     * 设置打卡时间，默认配置检查时间为早上9点后算迟到，晚上18:00算早退
     * @param userId 用户 id
     * @return ajax
     */
    @PostMapping("/leavePunch/{userId}")
    public AjaxResult leavePunch(@PathVariable Long userId){
        if(userId==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"userId不能为空！");
        }
        AjaxResult ajaxResult = AjaxResult.success();
        EmployeePunch employeePunch = punchService.selectOneEmployeePunchToday(userId);
        Date now = new Date();
        if(employeePunch==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"您未进行上班打卡！请先进行上班打卡！");
        }
        //如果进行过打卡，更新下班时间，并取消早退状态(由于工作需求可能存在打卡后任务，故允许更新下班时间)
        employeePunch.setEndTime(now);
        if(DateUtils.workPunchCheck(now,leaveEarlyTime)){
            if(EmployeePunch.PunchStatus.ArriveLate.getStatus()!=employeePunch.getPunchStatus()){
                employeePunch.setPunchStatus(EmployeePunch.PunchStatus.Normal.getStatus());
            }
        }else {
            //如果早退并迟到则设置迟到并早退参数
            if(EmployeePunch.PunchStatus.ArriveLate.getStatus()==employeePunch.getPunchStatus()){
                employeePunch.setPunchStatus(EmployeePunch.PunchStatus.ArriveLateAndLeaveEarly.getStatus());
            }
        }
        punchService.updateEmployeePunch(employeePunch);
        ajaxResult.put("punchTime",DateUtils.formatTime(now));
        return ajaxResult;
    }


    /**
     * 执行请假操作
     * @param employeeVacation employeeVacation 对象
     * @return Ajax参数
     */
    @PostMapping("/askForVacation")
    public AjaxResult askForVacation(@RequestBody EmployeeVacation employeeVacation){
        if(employeeVacation==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"错误，json对象不能为空！");
        }
        //判断如果已经有审批，并且未审核则驳回审批
        if(getUnCheckVacation(employeeVacation.getUserId())!=null){
            return AjaxResult.error(AjaxResult.StatusCode.HaveAskError.getCode(), "错误，已经有假期待审批！请勿重复请假！");
        }
        //判断是否参数为空
        if(employeeVacation.getVacationStartDate()==null || employeeVacation.getVacationEndDate()==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"错误，开始时间或结束时间不能为空！");
        }
        AjaxResult ajaxResult = AjaxResult.success();
        vacationService.insertEmployeeVacation(employeeVacation);
        return ajaxResult;
    }

    /**
     * 进行已查阅操作
     * @param employeeVacation employeeVacation对象
     * @return ajax参数
     */
    @PostMapping("/haveCheckVacation")
    public AjaxResult haveCheckVacationResult(@RequestBody EmployeeVacation employeeVacation){
        if(employeeVacation==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"错误，json对象不能为空！");
        }
        if(employeeVacation.getUserId()==null){
            return AjaxResult.error(AjaxResult.StatusCode.ExtraError.getCode(),"错误，用户id不能为空！");
        }
        //进行已查看操作
        employeeVacation.setDisplay(0);
        AjaxResult ajaxResult = AjaxResult.success();
        if(vacationService.updateEmployeeVacation(employeeVacation)==0){
            return AjaxResult.error("错误，服务器进行更新失败，请联系管理员！");
        }
        return ajaxResult;
    }

    /**
     * 进行是否存在未审批 假期参数，如果存在则返回对象，反之返回空
     * @return employeeVacation对象或null
     */
    private EmployeeVacation getUnCheckVacation(Long userId){
        EmployeeVacation vacation = new EmployeeVacation();
        vacation.setStatus("0");
        vacation.setUserId(userId);
        //由于逻辑默认只能有一个未审批参数，故直接return 0 即可，不存在则return null
        List<EmployeeVacation> employeeVacations = vacationService.selectEmployeeVacationList(vacation);
        if(employeeVacations.size()>0){
            return employeeVacations.get(0);
        }
        return null;
    }

    /**
     * 进行是否存在未审批 假期参数，如果存在则返回对象，反之返回空
     * @return employeeVacation对象或null
     */
    private EmployeeVacation setSaveVacation(){
        EmployeeVacation vacation = new EmployeeVacation();
        vacation.setStatus("0");
        //由于逻辑默认只能有一个未审批参数，故直接return 0 即可，不存在则return null
        List<EmployeeVacation> employeeVacations = vacationService.selectEmployeeVacationList(vacation);
        if(employeeVacations.size()>0){
            return employeeVacations.get(0);
        }
        return null;
    }
}
